Skip to content

Add a "Conversation width" setting (Comfortable / Wide / Full) to Appearance#63

Open
DragonnZhang wants to merge 2 commits into
mainfrom
loop/conversation-width
Open

Add a "Conversation width" setting (Comfortable / Wide / Full) to Appearance#63
DragonnZhang wants to merge 2 commits into
mainfrom
loop/conversation-width

Conversation

@DragonnZhang

Copy link
Copy Markdown
Collaborator

Closes #62

What & why

OpenWork rendered the chat transcript and the composer inside a single fixed
reading column — CHAT_LAYOUT.maxWidth = max-w-[840px] — with no way to change
it. On large/ultrawide displays that wastes most of the window, and code-heavy
conversations (wide diffs, long tool output, tables) get needlessly wrapped.

Comparable desktop clients all expose this: Claude Desktop (wider chat),
ChatGPT desktop (chat width), Codex / VS Code (content width). This adds
the same affordance to OpenWork's Appearance page.

Changes

  • context/ConversationWidthContext.tsx — new renderer-only preference
    (comfortable | wide | full), persisted in localStorage
    (craft-conversation-width), mirroring the merged ReduceMotionContext
    (Add a "Reduce motion" accessibility setting to Appearance #51). It reflects the choice onto <html> as data-conversation-width and
    drives a CSS custom property --chat-content-max-width (840px / 1100px /
    none).
  • ChatDisplay.tsx / ChatInputZone.tsx — the transcript container and the
    composer now read max-width: var(--chat-content-max-width, 840px). The
    840px fallback means the shared web viewer (packages/ui) and
    compact/popover embeddings are untouched.
  • AppearanceSettingsPage.tsx — a segmented control in the Interface
    section, right below "Reduce motion".
  • SettingsSegmentedControl.tsx — small, backward-compatible testId prop
    (group + per-option data-testid) for e2e targeting.
  • local-storage.ts — new conversationWidth key.
  • i18n — 5 new keys across all 7 locales (en, zh-Hans, de, es, ja,
    hu, pl).

Frontend-only — no qwen-code backend change.

Verification (DoD)

  • bun run typecheck:all — my files clean; zero-delta vs main (identical
    pre-existing error set).
  • bun testzero-delta vs main (56-failure baseline set byte-identical;
    i18n locale-parity outcomes unchanged).
  • bun run electron:build:renderer — ✅ builds (all changed code is renderer +
    locales).
  • CDP assertion e2e/assertions/conversation-width.assert.ts — drives the real
    Settings → Appearance UI, cycles all three options, and asserts for each: the
    radio aria-checked state, the data-conversation-width attribute on <html>,
    the computed --chat-content-max-width CSS variable (840px/1100px/none),
    and the persisted localStorage value — proving it applies and reverts.

Environment note: the CDP assertion could not be executed in this
sandbox
— outbound egress returns 403 for the Electron binary download and
for the libsignal-node / whiskeysockets/eslint-config git-tarball deps, so
electron:build:main, the full bun run build lint step, and launching Electron
all fail before the app starts. These are pre-existing environment blockers
(the same egress limit recorded for the merged #51), not regressions from this
change. The assertion mirrors the merged reduce-motion assertion's exact CDP API
and is ready to run in CI where the Electron binary is available.


Generated by Claude Code

…earance

Adds a renderer-only "Conversation width" preference to Settings →
Appearance → Interface, letting users widen the chat transcript and
composer beyond the fixed 840px reading column — matching the width
controls in Claude Desktop, ChatGPT desktop and Codex / VS Code.

- New ConversationWidthProvider (localStorage `craft-conversation-width`,
  mirroring ReduceMotionContext) reflects the choice onto `<html>` as
  `data-conversation-width` and drives a `--chat-content-max-width` CSS
  variable (840px / 1100px / none).
- ChatDisplay transcript container and ChatInputZone read the variable via
  `max-width: var(--chat-content-max-width, 840px)`; the fallback leaves the
  shared web viewer unchanged and compact/popover embeddings untouched.
- Segmented control in the Appearance Interface section; adds an optional
  `testId` to SettingsSegmentedControl for e2e targeting.
- 5 new i18n keys across all 7 locales.
- CDP assertion drives the real Settings UI, cycling all three options and
  asserting the radio state, `<html>` attribute, computed CSS variable and
  persisted localStorage value.

Closes #62
@DragonnZhang DragonnZhang added enhancement New feature or request loop-bot labels Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request loop-bot

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a "Conversation width" setting (Comfortable / Wide / Full) to Appearance

2 participants